function SpTabControl() {
  var _pages = new Array();
  var _instance = this;
  var _id;
  var _util = Library.WebControl.Util;
  var _enable;
  var _tabIndexChanged = null;
  var _tabIndexChanging = null;
  var _showClose = false;
  this.Init = function(clientName, showCloseButton, id, enable) {
    _globalHashObject.Add(clientName, _instance);
    window[clientName] = _instance;
    _id = id;
    _enable = enable;
    _showClose = showCloseButton;
  };

  function showContent(tab, tabName) {
    tab.Foreach(function(s, e) {
      if (s.GetClass() == "spTabContent") {
        if (getTabName(s) == tabName) {
          s.style.display = "";
        } else {
          s.style.display = "none";
        }
      }
    });
  };
  function getTabName(s) {
    return s.GetAtt("_tabname");
  };

  function findMenu(id) {
    var tab = _util.GetObjectById(_id);
    var titles = tab.FindFirstChild("div", "spTabTitleContent", true);
    var arr = findMenuByTitle(titles, id);
    return [tab, arr[0], arr[1], arr[2], arr[3]];
  };
  function findMenuByTitle(titles, id) {
    var isName = typeof (id) == "string";
    var active = null;
    var activeIndex = -1;
    var next = null;
    var nextIndex = -1;
    titles.Foreach(function(s, e) {
      var clazz = s.GetClass();
      if (clazz == "active") {
        active = s;
        activeIndex = e.ElementIndex;
      }
      if (isName) {
        var tabName = getTabName(s);
        if (tabName == id) {
          next = s;
          nextIndex = e.ElementIndex;
        }
      } else {
        if (e.ElementIndex == id) {
          next = s;
          nextIndex = e.ElementIndex;
        }
      }
      e.Break = next != null && active != null;
    });
    return [active, activeIndex, next, nextIndex];
  };


  this.AddTab = function(name, text, content) {
    var tab = _util.GetObjectById(_id);
    var titles = tab.FindFirstChild("div", "spTabTitleContent", true);
    var a = document.createElement("a");
    titles.appendChild(a);
    a.setAttribute("href", "javascript:void(0)");
    a.setAttribute("_tabname", name);
    a.onclick = function() { _instance.SelectTab(this); };
    var span = document.createElement("span");
    a.appendChild(span);
    var strong = document.createElement("strong");
    span.appendChild(strong);
    var textElement = document.createElement("text");
    strong.appendChild(textElement);
    textElement.innerHTML = text;
    if (_showClose) {
      var b = document.createElement("b");
      b.onclick = function() { _instance.CloseTab(this); };
      strong.appendChild(b);
    } else {
      var txt = document.createElement("txt");
      strong.appendChild(txt);
    }

    var divContent = document.createElement("div");
    tab.appendChild(divContent);
    _util.SetClass(divContent, "spTabContent");
    divContent.setAttribute("_tabname", name);
    switch (typeof (content)) {
      case "string":
        divContent.innerHTML = content;
        break;
      default:
        divContent.appendChild(content);
        break;
    }
    _instance.SelectTab(name);
  };

  this.SelectTab = function(o) {
    var tab = null;
    var active = null;
    var activeIndex = -1;
    var next = null;
    var nextIndex = -1;

    var t = typeof (o);
    switch (t) {
      case "number":
      case "string":
        var menus = findMenu(o);
        tab = menus[0];
        active = menus[1];
        activeIndex = menus[2];
        next = menus[3];
        nextIndex = menus[4];
        break;
      default: //object
        o = _util.GetObjectById(o);
        if (o.GetClass() == "active") return;
        var titles = o.FindParent("div", "spTabTitleContent");
        var arr = findMenuByTitle(titles, getTabName(o));
        tab = _util.GetObjectById(_id);
        active = arr[0];
        activeIndex = arr[1];
        next = arr[2];
        nextIndex = arr[3];
        break;
    }
    if (tab != null && next != null) {
      var nextTabName = getTabName(next);
      if (active != null) {
        if (nextTabName == getTabName(active)) return;
        var evt = new Object();
        evt.Cancel = false;
        evt.CurIndex = activeIndex;
        evt.NewIndex = nextIndex;
        if (_tabIndexChanging != null)
          _tabIndexChanging(_instance, evt);
        if (evt.Cancel) return;

        active.SetClass("");
      }
      next.SetClass("active");
      showContent(tab, nextTabName);
      if (_tabIndexChanged != null)
        _tabIndexChanged(_instance, { Index: nextIndex });
    }
  };

  this.CloseTab = function(o) {
    var tabPage = null;
    var t = typeof (o);
    switch (t) {
      case "number":
      case "string":
        tabPage = _instance.FindTab(o);
        break;
      default:
        tabPage = _instance.FindTab(o.getAttribute("_tabname"));
        break;
    }
    if (tabPage != null) {
      if (tabPage.IsActive) {
        var next = tabPage.Menu.NextElement();
        if (next == null) next = tabPage.Menu.PreviewElement();
        if (next != null) {
          next.SetClass("active");
          showContent(_util.GetObjectById(_id), getTabName(next));
        }
      }
      var tab = tabPage.Menu.FindParent("div", "spTabControl");
      tabPage.Menu.parentNode.removeChild(tabPage.Menu);
      tab.Foreach(function(s, e) {
        if (getTabName(s) == tabPage.Name) {
          e.Break = true;
          tab.removeChild(s);
        }
      });
    }
  };



  this.GetSelectedIndex = function() {
    return _instance.GetSelectedTab().Index;
  };
  this.GetSelectedTab = function() {
    return _instance.FindTab(null);
  };
  this.FindTab = function(id) {
    var isActive = id == null || typeof (id) == "undefined";
    var isName = typeof (id) == "string";
    var selectedTab = { Name: "", Index: -1, Content: null, Menu: null, IsActive: false };
    var tab = _util.GetObjectById(_id);
    var titles = tab.FindFirstChild("div", "spTabTitleContent", true);
    titles.Foreach(function(s, e) {
      if ((isActive && s.GetClass() == "active") || (!isActive && isName && getTabName(s) == id) || (!isActive && !isName && e.ElementIndex == id)) {
        e.Break = true;
        selectedTab.Name = getTabName(s);
        selectedTab.Index = e.ElementIndex;
        selectedTab.Menu = s;
        selectedTab.IsActive = s.GetClass() == "active";
      }
    });
    if (selectedTab.Name == "") return null;
    tab.Foreach(function(s, e) {
      if (getTabName(s) == selectedTab.Name) {
        e.Break = true;
        selectedTab.Content = s;
      }
    });
    selectedTab.SetActive = function() {
      if (this.IsActive) return;
      _instance.SelectTab(this.Name);
    };
    selectedTab.title = function() {
      var txt = this.Menu.FindFirstChild("text", null, true);
      if (arguments.length > 0) {
        txt.innerHTML = arguments[0];
      }
      return txt.innerHTML;
    };
    return selectedTab;
  };
  this.SetVisible = function(visible) {
    var display = visible ? "" : "none";
    _util.GetObjectById(_id).style.display = display;
  };
  this.GetVisible = function() {
    return _util.GetObjectById(_id).style.display != "none";
  };

  this.SetEnable = function(enable) {
    _enable = enable;
  };
  this.GetEnable = function() {
    return _enable;
  };
  this.AddHandler = function(t, f) {
    switch (t) {
      case 1:
        _tabIndexChanged = f;
        break;
      case 2:
        _tabIndexChanging = f;
        break;
    }
  };

};
